package com.dhq.myapp.util.http

import android.content.Context
import com.dhq.myapp.entity.BaseResponse
import com.dhq.myapp.util.LogUtil
import com.dhq.myapp.util.NetWorkUtils
import com.dhq.myapp.util.dialog.DialogUtils
import com.dhq.myapp.util.dialog.listener.DialogListener
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonSyntaxException
import com.lxj.xpopup.core.BasePopupView
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import java.lang.reflect.ParameterizedType

/**
 * DESC
 * Created by admin on 2017/2/14.
 */
abstract class BaseObserver<T> : Observer<JsonElement> {

    companion object {
        private const val TAG = "BaseObserver"
    }

    protected val gson: Gson = GsonBuilder()
        .registerTypeAdapter(String::class.java, StringNullAdapter())
        .create()

    protected var mContext: Context? = null
    protected var mDisposable: Disposable? = null
    protected var myDialog: BasePopupView? = null
    protected var mLastShow: Boolean = true //是否显示错误弹框

    protected var mResponse: JsonElement? = null

    /**
     * 不显示弹框
     */
    constructor()

    /**
     * 显示弹框(请求前后都显示)
     */
    constructor(context: Context) {
        mContext = context
    }

    /**
     * 显示弹框
     */
    constructor(context: Context, lastShow: Boolean) {
        mContext = context
        mLastShow = lastShow
    }

    override fun onSubscribe(d: Disposable) {
        this.mDisposable = d

        if (mContext != null && !NetWorkUtils.isNetworkConnected(mContext!!)) {
            showError("网络不可用")
            cancle()
            return
        }

        showWaitingDialog()
    }

    override fun onNext(response: JsonElement) {
        mResponse = response
    }

    override fun onError(e: Throwable) {
        LogUtil.e(e.toString())
        hintWaitingDialog()

        val netException = NetException(e)
        fail(netException.errorCode, netException.errorMsg)
    }

    override fun onComplete() {
        hintWaitingDialog()

        if (mResponse == null) {
            showError("请求数据错误")
            return
        }

        val baseResp = gson.fromJson(mResponse, BaseResponse::class.java)

        //验证请求状态
        if ("200" != baseResp.code) {
            showError(baseResp.message!!)
            return
        }

        try {
            if (getData(mResponse!!, baseResp) == null) {
                success(null)
            } else {
                val parameterizedType = this.javaClass.genericSuperclass as ParameterizedType
                val type = parameterizedType.actualTypeArguments[0]
                if (type != null) {
                    val data = gson.fromJson<T>(getData(mResponse!!, baseResp), type)
                    success(data)
                } else {
                    success(null)
                }
            }
        } catch (e: JsonSyntaxException) {
            e.printStackTrace()
            showError("解析数据错误！")
        }
    }

    private fun showError(msg: String) {
        if (mContext != null && mLastShow==true) {
            //显示错误弹框
            DialogUtils.getInstance(mContext!!)
                .setTitle("温馨提示")
                .setContent(msg)
                .setComfirmListener("确定", object : DialogListener {
                    override fun onClickListener(popupView: BasePopupView?) {
                        popupView?.dismiss()
                    }
                }).bulid().showCenterDialog()
        }

        fail(msg)
    }

    /**
     * 解除网络请求绑定
     */
    fun cancle() {
        mDisposable?.dispose()
    }

    /**
     * 显示网络请求等待框
     */
    private fun showWaitingDialog() {
        if (mContext == null) {
            return
        }
        myDialog = DialogUtils.getInstance(mContext!!)
            .setTitle("加载中")
            .setCanDismiss(false)
            .bulid()
            .showLoadingDialog()
    }

    /**
     * 取消等待框
     */
    private fun hintWaitingDialog() {
        myDialog?.dismiss()
    }

    /**
     * 获取泛型T的Class
     */
    fun getEntityClass(): Class<T>? {
        val t = javaClass.genericSuperclass
        var entityClass: Class<T>? = null
        if (t is ParameterizedType) {
            val p = t.actualTypeArguments
            entityClass = p[0] as Class<T>
        }
        return entityClass
    }

    protected open fun getData(result: JsonElement, response: BaseResponse): JsonElement? {
        return response.data
    }

    /**
     * 请求成功
     */
    abstract fun success(result: T?)

    /**
     * 请求失败
     */
    abstract fun fail(msg: String)

    /**
     * 请求失败
     */
    open fun fail(errorCode: Int, msg: String) {
        showError(msg)
    }
}

// NetException类需要单独定义（根据原Java代码推断）
class NetException(e: Throwable) {
    val errorCode: Int = 0
    val errorMsg: String = e.message ?: "网络异常"
}
